home *** CD-ROM | disk | FTP | other *** search
/ Mac Expert 1995 Winter / Mac Expert - Winter 95.iso / Les fichiers / Communications / Divers / DinkClass ƒ / DinkClass / DDocument.c < prev    next >
Encoding:
Text File  |  1992-12-31  |  10.6 KB  |  547 lines  |  [TEXT/KAHL]

  1. /*
  2.     File:        DDocument.cp
  3.  
  4.     Contains:    xxx put contents here xxx
  5.  
  6.     Written by:    Mark Gross
  7.  
  8.     Copyright:    © 1992 by Applied Technical Software, all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <6>    12/31/92    MTG        making the code conditionaly compiled so         that I am
  13.                                     always working with a current         version in either think c
  14.                                     or MPW C++
  15.          <5>    11/14/92    MTG        Bringing the C++ version up to date WRT the ThinkC version.
  16.          <4>     9/20/92    MTG        Bringing this C++ code uptodate with the THINK C version
  17.          <3>      8/9/92    MTG        merging changes from the ThinkC version
  18.          <2>      8/8/92    MTG        cleaning up un used variables
  19.  
  20.     To Do:
  21. */
  22.  
  23. // the is the Class definition for the DDocument class
  24.  
  25.  
  26. #include "DDocument.h"
  27. #include "DWindow.h"
  28. #include "DScrollWindow.h"
  29. #include "DEventHandler.h"
  30. #include "DApplication.h"
  31. #include <string.h>
  32.  
  33. DDocument::DDocument(void)
  34. {
  35.     fDWindow = NULL;
  36.     fDataHandle = NULL;
  37.     fFileRef = 0;
  38.     fKMNxtCalledFromWindow = FALSE;
  39.     fNeedToSave = FALSE;    
  40. }
  41.  
  42.  
  43. DDocument::~DDocument()
  44. {
  45.     DisposPtr( (Ptr) fFileReply);
  46.     if (fFileRef != 0) 
  47.         FSClose(fFileRef);
  48.         
  49.     if(fDataHandle != NULL)
  50.     {
  51.         DisposHandle(fDataHandle);
  52.         fDataHandle = NULL;
  53.     }
  54. }// end of document destructor
  55.  
  56.         
  57. DDocument* DDocument::Init( Boolean OpenExistingFile)
  58. {
  59.     SFTypeList localTypeList;
  60.     
  61.     fDWindow = NULL;
  62.     fDataHandle = NULL;
  63.     fFileRef = 0;
  64.     fFileReply = (StandardFileReply *)NewPtr( sizeof(StandardFileReply) );
  65.     
  66.     fNeedToSave = FALSE;
  67.     
  68.     fNextHandler = gApplication;
  69.     fCreator = gApplication->fCreator;
  70.     
  71.     gApplication->GetFileType(localTypeList);
  72.     fFileType = localTypeList[0];
  73.     
  74.     if (OpenExistingFile)
  75.     {
  76.         SellectFile(fFileReply);
  77.         if( fFileReply->sfGood)
  78.         {
  79.             fFileType = fFileReply->sfType;
  80.             if(FALSE == OpenFile( &(fFileReply->sfFile)) )
  81.                  return NULL; 
  82.          }// end if user didn't cancel
  83.          else
  84.              return NULL;
  85.     }
  86.     else
  87.     {
  88.         fNeedToSave = FALSE;
  89.     }
  90.     
  91.     return this;
  92.         
  93. }//end member function Init
  94.  
  95.  
  96. void DDocument::AEInitDoc(FSSpec *theFSS)
  97. {
  98.     SFTypeList localTypeList;
  99.     StringPtr title;
  100.     
  101.     fDWindow = NULL;
  102.     fDataHandle = NULL;
  103.     fFileRef = 0;
  104.     fFileReply = (StandardFileReply *)NewPtr( sizeof(StandardFileReply) );
  105.     
  106.     BlockMove( theFSS, &(fFileReply->sfFile), sizeof(FSSpec));
  107.             // we need to copy the FSSpec to the fFileReply member
  108.             // for the Save() function to opperate correctly.    
  109.     fNeedToSave = FALSE;
  110.     
  111.     fNextHandler = gApplication;
  112.     fCreator = gApplication->fCreator;
  113.     
  114.     gApplication->GetFileType(localTypeList);
  115.     fFileType = localTypeList[0];
  116.     
  117.     OpenFile( theFSS );
  118.     title = theFSS->name;
  119.  
  120.     MakeWindow(HasColorQD());
  121.     if(fFileRef != 0) //fFileRef is the file open flag, if its false then we just opened a
  122.         SetWTitle(fDWindow->fWindowPtr, title); // stationary pad.
  123.         
  124. }//end member function AEInitDoc
  125.  
  126.  
  127.  
  128. Boolean DDocument::DoSaveAs(void)
  129. {
  130.     if (fFileRef != 0) 
  131.         FSClose(fFileRef);
  132.         
  133.     fFileRef = 0;
  134.     
  135.     return SaveFile();;
  136. }// end of member function DoSaveAs
  137.  
  138.  
  139.  
  140. Boolean DDocument::WindowClosed(DWindow *deadWindow)
  141. {
  142.     short saveit;
  143.         
  144.     if( fNeedToSave )
  145.     {
  146.         saveit = WantToSave(fDWindow->fWindowPtr);
  147.         if(saveit == iYes)
  148.         {
  149.             if(SaveFile())
  150.             {
  151.                 fKMNxtCalledFromWindow = TRUE;
  152.                 KillMeNext();
  153.                 return TRUE;
  154.             }
  155.             else
  156.             {
  157.                 gApplication->fDone = FALSE;// if quitting then user has change thier mind....
  158.                 return FALSE;// USER CALNCELD OPPERATION!!!
  159.             }
  160.         }
  161.         else if (saveit == iCancel)
  162.         {
  163.             gApplication->fDone = FALSE;// if quitting then user has change thier mind....
  164.             return FALSE;// USEER CANCELED THE OPPERATION!!!!!
  165.         }
  166.     }
  167.     if( fDataHandle)
  168.     {
  169.         DisposHandle( fDataHandle);
  170.         fDataHandle = NULL;
  171.     }
  172.  
  173.     fKMNxtCalledFromWindow = TRUE;
  174.     KillMeNext();
  175.     return TRUE;
  176.     
  177. }// end of member function WindowClosed
  178.  
  179.  
  180. //
  181. // DDocument::KillMeNext has 2 entry points, one from windowclosed
  182. // the other is hidden in DApplciation::CleanUp.  
  183. // Hence, I do noting and return FALSE unless the call comes from 
  184. // WindowClosed.
  185. //
  186. Boolean DDocument::KillMeNext(void)
  187. {
  188.     Boolean inheritedSuccess = FALSE;
  189.  
  190.     if(fAlive) // fAlive flag is here to make the 
  191.     {            // kill them all process of quitting function correctly
  192.                 // Without it, is code could be exicuted 2 times.
  193.                 // Resulting in two WantToSave calls at best, crash at worst.
  194.         if (fKMNxtCalledFromWindow )        
  195.             inheritedSuccess = inherited::KillMeNext();
  196.  
  197.         return inheritedSuccess;// only TRUE if called from fDWindow...
  198.     }
  199.  
  200.     return inheritedSuccess;
  201. }//end of KillMeNext method.
  202.  
  203.  
  204. DWindow* DDocument::MakeWindow(Boolean hasColorWindows)
  205. {    
  206.     DWindow *newWindow;
  207.     
  208.     //newWindow = new DWindow;
  209.     newWindow = new DScrollWindow;
  210.     fDWindow = newWindow;
  211.         
  212.     if (newWindow->Init(this, hasColorWindows))
  213.         return newWindow;
  214.     else
  215.     {
  216.         fDWindow = NULL;
  217.         return fDWindow;
  218.     }    
  219. }//end member function MakeWindow
  220.  
  221.  
  222.  
  223. short DDocument::WantToSave(WindowPtr theWindow)
  224. {
  225.     Str255    title;
  226.     Str255    nullStr;
  227.     
  228.     *nullStr = 0;
  229.     
  230.     if(theWindow)
  231.     {
  232.         GetWTitle(theWindow, title);
  233.         ParamText(title, nullStr, nullStr, nullStr);
  234.     }
  235.     else
  236.         ParamText(nullStr,nullStr,nullStr,nullStr);
  237.     
  238.     return Alert(rWantToSave, NULL);
  239. }// end of WantToSave member function
  240.  
  241.  
  242. //
  243. // DEventHandler overrides
  244. //
  245.  
  246. void DDocument::HandleMenuChoice(short menuID, short menuItem)
  247. {
  248.     if( menuID == rFileMenu)
  249.     {
  250.         switch (menuItem)
  251.         {
  252.             case iSave:
  253.                 SaveFile();
  254.                 break;
  255.                 
  256.             case iSaveAs:
  257.                 DoSaveAs();
  258.                 break;
  259.                 
  260.             case iClose:
  261.                 fDWindow->KillMeNext(); // the Window then informs document that its ok to rest in peace.
  262.                 break;
  263.  
  264.             case iPrint:
  265.                 fDWindow->DoPrint();
  266.                 break;
  267.  
  268.             case iPageSetup:
  269.                 fDWindow->DoPageSetUp();
  270.                 break;
  271.  
  272.             default:
  273.                 break;
  274.         }// end switch on menuItem
  275.     }// end if fileMenu
  276.     
  277.     inherited::HandleMenuChoice( menuID, menuItem);
  278. }            
  279.  
  280. void DDocument::SetUpMenues(void)
  281. {
  282.     MenuHandle    menu;
  283.     
  284.     menu = GetMHandle(rFileMenu);
  285.     EnableMenuItem( menu, iClose, TRUE);
  286.     //EnableMenuItem( menu, iSave, TRUE);
  287.     //EnableMenuItem( menu, iSaveAs, TRUE);
  288.     //EnableMenuItem( menu, iPageSetup, TRUE);
  289.     //EnableMenuItem( menu, iPrint, TRUE);
  290.     
  291.     
  292.     inherited::SetUpMenues( );
  293. }
  294.  
  295.  
  296.  
  297. void    DDocument::DoCut(void)
  298. {
  299.     
  300. }// end of DoCut member function
  301.  
  302.  
  303. void    DDocument::DoCopy(void)
  304. {
  305. }// end of DoCopy member function
  306.  
  307.  
  308. void    DDocument::DoPaste(void)
  309. {
  310.     // big STUB!!!
  311. }
  312.  
  313. void    DDocument::DoClear(void)
  314. {
  315.     // big STUB!!!
  316. }
  317.  
  318.  
  319. void    DDocument::DoUndo(void)
  320. {
  321.     // big STUB!!!
  322. }
  323.  
  324.  
  325. void    DDocument::DoSellectAll(void)
  326. {
  327.     // big STUB!!!
  328. }
  329.  
  330.  void DDocument::SellectFile(StandardFileReply* reply)
  331. {
  332.     SFTypeList theTypeList;
  333.     int numOfTypes;
  334.             
  335.     numOfTypes = gApplication->GetFileType(theTypeList);
  336.     
  337.     StandardGetFile(NULL, numOfTypes, theTypeList, reply);
  338.     
  339. }// end member function SellectFile
  340.  
  341.  
  342.             
  343.     
  344.         
  345. Boolean DDocument::OpenFile(FSSpecPtr specPtr)
  346. {
  347.     OSErr fileError;
  348.     short fileRef;
  349.     long dataCount;
  350.     Boolean isStationary;
  351.     FInfo theFInfo;
  352.  
  353.     
  354.     fileError = FSpOpenDF( specPtr, fsCurPerm, &fileRef);
  355.     if(fileError != noErr)
  356.     {
  357.         if(fileError == opWrErr)
  358.             ErrorAlert(rErrorStrings, sFileOpen);
  359.         else
  360.             ErrorAlert(rErrorStrings, sUnknownErr);
  361.                 
  362.          return FALSE;
  363.     }
  364.     fFileRef = fileRef; // ok, we have an open file lets try to get
  365.                         // the length of this guy.
  366.     
  367.     fileError = GetEOF( fileRef, &dataCount);
  368.     if(fileError != noErr)    
  369.     {
  370.         FSClose(fileRef);
  371.         fFileRef = 0;
  372.         return FALSE;
  373.     }
  374.  
  375. //
  376. // Ok, we've gotten this far, the file is open and
  377. // its time to read the data.
  378. //
  379.     if( ReadData(fileRef, &dataCount) != noErr)
  380.     {
  381.         FSClose(fileRef);
  382.         fFileRef = 0;
  383.         return FALSE;
  384.     }
  385.  
  386.     FSpGetFInfo(specPtr, &theFInfo); //get finder info to check for stationary padness
  387.     
  388.     isStationary = ( (theFInfo.fdFlags & 0x800) != 0);
  389.     if(isStationary)
  390.     {
  391.         FSClose(fileRef);// close that file and set
  392.         fFileRef = 0;    // the flag indicating that no file has been opened (keep the window untitled!
  393.         fNeedToSave = TRUE;
  394.     }
  395.     
  396.     return TRUE;
  397. }// end member function OpenFile
  398.  
  399.  
  400.  
  401. OSErr DDocument::ReadData(short refNum, long *size)
  402. {
  403.     OSErr fileError;
  404.     Handle data;
  405.  
  406. //
  407. // first make some place to put the data
  408. //
  409.     data = NewHandle(*size);
  410.     if(data == NULL)
  411.         return memFullErr;
  412. //
  413. // get it ready, and read into the space...
  414. //    
  415.     HLock(data);
  416.     fileError = FSRead(refNum, size, *data);
  417.     HUnlock(data);
  418.  
  419. //
  420. // if problem, free space up an return error.
  421. //    
  422.     if(fileError != noErr)
  423.     {
  424.         DisposHandle( data);
  425.         return fileError;
  426.     }
  427. //
  428. // otherwise put the data in an object member, for your use.
  429. // note that your overrides of this need not use fDataHandle.
  430. // In fact fDataHandle realy shouldn't be in this class,  your
  431. // sub-classes should have thier own place to put thier data.
  432. // (its here for guidence)
  433. //    
  434.     fDataHandle = data;
  435.     return fileError;    
  436. }// end member function ReadData
  437.  
  438.  
  439.  
  440.  
  441. Boolean DDocument::SaveFile(void)
  442. {
  443.     OSErr fileError;
  444.     FSSpecPtr specPtr;
  445.     short refNum;
  446.     FInfo theFInfo;
  447.     StandardFileReply* reply;            
  448.     
  449.     if (fFileRef == 0)    // then we need to save as, and better define a file for it.
  450.     {
  451.         reply = fFileReply;
  452.         StandardPutFile("\pSave file as:", "\pUntitled", reply);
  453.         fFileReply = reply;
  454.     }
  455.     else
  456.     {
  457.         FSClose(fFileRef);
  458.         fFileRef = 0;
  459.         fFileReply->sfReplacing = TRUE;
  460.     }
  461.     
  462.     if(!fFileReply->sfGood)
  463.     {
  464.         return FALSE;
  465.         // user canceled save opperation
  466.     }
  467.     
  468.     
  469.     specPtr = &(fFileReply->sfFile);
  470. //
  471. // Buffer up any finder info stuff the file may have, so that we
  472. // may transfrer to the replaceing file yet to be created.
  473. //    
  474.     if( fFileReply->sfReplacing)
  475.     {
  476.         FSpGetFInfo(specPtr, &theFInfo); //get finder info BEFORE the file is deleted
  477.         fFileReply->sfFlags = theFInfo.fdFlags; // keep it correct for the file to be created...
  478.         
  479.         fileError = FSpRstFLock(specPtr);
  480.         if( !((fileError == fnfErr) || (fileError == noErr)) )
  481.             return FALSE;
  482.     
  483.         if(fileError == noErr)
  484.         {
  485.             fileError = FSpDelete(specPtr);//risky for my liking, but its the easy way to do files.
  486.             if(fileError != noErr)
  487.                 return FALSE;
  488.         }
  489.     }
  490.     fileError = FSpCreate( specPtr, gApplication->fCreator, 
  491.                 fFileType, reply->sfScript);
  492.                 
  493.     if ( fileError != noErr)
  494.         return FALSE;
  495.     if( fFileReply->sfReplacing)
  496.         FSpSetFInfo(specPtr, &theFInfo);
  497. //        
  498. // regardless if a save as was done, we now have a closed file redy to be written
  499. // too and it needs opening. We may have deleted
  500. // and open file, too bad.
  501. //
  502.  
  503.     fileError = FSpOpenDF(specPtr, fsCurPerm, &refNum);
  504.     if ( fileError != noErr)
  505.         return FALSE;
  506.  
  507. // 
  508. // Now we are ready to write the data out.
  509. //        
  510.     fileError = WriteData(refNum);
  511.     if ( fileError != noErr)
  512.         return FALSE;
  513.         
  514.     fFileRef = refNum;    
  515.     fNeedToSave = FALSE;
  516.     return TRUE;
  517.     
  518. }//end member function SaveFile
  519.  
  520.  
  521.  
  522.  
  523. OSErr DDocument::WriteData(short refNum)
  524. {
  525.     OSErr fileError;
  526.     Handle data;
  527.     long dataCount;
  528.  
  529. //
  530. // get the data into a local var and get its size
  531. //
  532.     data = fDataHandle;
  533.     if(data == NULL)
  534.         return FALSE;
  535.     dataCount = GetHandleSize(data);
  536.     
  537. //
  538. // Lock that pup down and write out the info
  539. //
  540.     HLock(data);
  541.     fileError = FSWrite(refNum, &dataCount, *data);
  542.     HUnlock(data);
  543.     
  544.     return fileError;    
  545. }//end member function WriteData
  546.  
  547.